package org.dark.fund.aspect;


import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Slf4j
@Configuration
public class ControllerLogAop {

    // 定义切点Pointcut
    @Pointcut("execution(* org.dark.fund.web.*.*(..))")
    public void excudeService() {
    }

    //@Around("execution(* com.bowei.officialwebsite.controller.*Controller.*(..))")//直接引用
    @Around("excudeService()") //引用public void excudeService()方法
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();

        String method = httpServletRequest.getMethod();
        String methodName = pjp.getSignature().getName();
        String controller = pjp.getTarget().getClass().getName();
        String uri = httpServletRequest.getRequestURI();
        String params = JSONUtil.toJsonStr(httpServletRequest.getParameterMap());

        log.info("Uri         : {}", uri);
        log.info("Controller  : {}", controller + getTargetStack(controller));
        log.info("Method      : {}", method);
        log.info("MethodName  : {}", methodName);
        log.info("Params      : {}", params);
        Object result = pjp.proceed();//获得拦截方法的返回值
        log.info("end controller: {}", JSONUtil.toJsonStr(result));
        return result;
    }

    /**
     * 用StringBuffer定位调用的controller层 定位第一行
     * @param tag
     * @return
     */
    private static String getTargetStack(String tag) {
        StringBuffer sb = new StringBuffer();
        int number = tag.lastIndexOf(".");//找到controller名称中最后一个.的索引
        String controller = tag.substring(number + 1);//截取controller的名字
        sb.append(".(" + controller).append(".java:1)");//定位在controller类里面的第一行
        return sb.toString();
    }

}

